<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet"/>
    <link href="https://ai-public.mastergo.com/gen_page/tailwind-custom.css" rel="stylesheet"/>
    <style id="animation-styles"> 
        @keyframes gradient { 
            0% { background-position: 0% 50%; } 
            50% { background-position: 100% 50%; } 
            100% { background-position: 0% 50%; } 
        }
    </style>
    <link rel="preconnect" href="https://fonts.googleapis.com"/>
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin=""/>
    <link href="https://fonts.googleapis.com/css2?family=Pacifico&display=swap" rel="stylesheet"/>
    <script src="https://cdn.tailwindcss.com/3.4.5?plugins=forms@0.5.7,typography@0.5.13,aspect-ratio@0.4.2,container-queries@0.1.1"></script>
    <script src="https://ai-public.mastergo.com/gen_page/tailwind-config.min.js" data-color="#AC1BF5" data-border-radius="medium"></script>
    <script src="https://cdn.staticfile.org/vue/3.4.5/vue.global.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
</head>
<body>
    <div id="splash" class="fixed inset-0 bg-black flex items-center justify-center z-50">
        <h1 class="text-7xl font-[&#39;Pacifico&#39;] text-white opacity-0 transition-opacity duration-1000 animate-bounce">
            Wow! It's WOW-RAG!
        </h1>
    </div>
    <div id="app" class="hidden h-screen bg-gradient-to-br from-purple-100 via-blue-100 to-purple-100 bg-[size:400%_400%] relative overflow-hidden">
        <div class="absolute inset-0 animate-[gradient_10s_linear_infinite] z-0">
            <div class="animate-pulse absolute w-64 h-64 bg-custom/10 rounded-full -top-32 -left-32"></div>
            <div class="animate-pulse absolute w-96 h-96 bg-blue-200/20 rounded-full -bottom-48 -right-48"></div>
        </div>
        
        <div class="container mx-auto h-full max-w-4xl px-4 py-6 flex flex-col">
            <div id="chatContainer" class="flex-1 overflow-y-auto mb-4 space-y-4 h-[calc(100%-120px)] z-20">
                <div v-for="item in messageList.filter((v) => v.role !== 'system')" class="flex" :class="{ 'justify-start': item.role === 'me', 'justify-end': item.role !== 'me' }">
                    <div class="max-w-[70%] space-y-1">
                        <div class="text-xs text-gray-500">{[ roleAlias[item.role] ]}</div>
                        <div class="rounded-lg p-3 shadow-sm" :class="{'bg-custom text-white': item.role !== 'me', 'bg-white': item.role === 'me'}">
                            <p v-html="markdownToHtml(item.content)"></p>
                        </div>
                    </div>
                </div>
            </div>
            <div class="bg-white/80 backdrop-blur-sm rounded-lg p-4 shadow-lg">
                <div class="flex items-center space-x-2">
                    <button class="text-gray-500 hover:text-custom">
                        <i class="far fa-smile text-xl"></i>
                    </button>
                    <textarea
                        id="messageInput"
                        class="flex-1 bg-transparent border-none focus:ring-0 text-gray-800 placeholder-gray-400"
                        placeholder="请输入您的问题..."
                        v-model="messageContent"
                        rows="3"
                    ></textarea>
                    <button id="sendButton" class="bg-custom text-white px-4 py-2 rounded-lg hover:bg-custom/80 transition-colors !rounded-button" @click="send()">
                        <i class="fas fa-paper-plane"></i>
                    </button>
                </div>
            </div>
        </div>
    </div>
    <script>
        async function fetchStream(param) {  
            const url = `http://127.0.0.1:5000/stream_chat?param=${encodeURIComponent(param)}`;
            const response = await fetch(url);  
            const reader = response.body.getReader();  

            while (true) {  
                const { value, done } = await reader.read();  

                if (done) {  
                    statusvue.isTalking = false;  
                    break; 
                }  

                const text = new TextDecoder("utf-8").decode(value);  
                let len = statusvue.messageList.length;
                statusvue.messageList[len-1].content += text; 
            }  
        }

        const app = Vue.createApp({
            data() {
                return {
                    cdata: [1, 0, 0],
                    roleAlias: { "me": "我", "GPT": "小助手", "system": "机器人" },
                    messageList: [
                        { "role": "system", "content": "你是一个人工智能答疑机器人,擅长借助RAG文档帮助用户进行问题回答" },
                        { "role": "GPT", "content": "您好！我是WOW-RAG智能助手，很高兴为您服务。" },
                    ],
                    isTalking: false,
                    messageContent: "",
                }
            },
            delimiters: ['{[', ']}'],
            methods: {
                send() {
                    const userMessage = this.messageContent.trim();
                    if (!userMessage) return;

                    // 添加用户消息
                    this.messageList.push({ "role": "me", "content": userMessage });
                    const message = document.getElementById('chatContainer');
                    message.scrollTop = message.scrollHeight;

                    // 添加助手消息占位符
                    this.messageList.push({ "role": "GPT", "content": "" });
                    this.isTalking = true;

                    // 发送请求
                    fetchStream(userMessage).then(() => {
                        this.isTalking = false;
                    });

                    this.messageContent = '';
                },
                // 新增方法：将 Markdown 转换为 HTML
                markdownToHtml(markdown) {
                    return marked.parse(markdown);
                }
            }
        })

        const statusvue = app.mount('#app');

        document.addEventListener('DOMContentLoaded', () => {
            const splash = document.getElementById('splash');
            const app = document.getElementById('app');
            const splashText = splash.querySelector('h1');
            const playPauseBtn = document.getElementById('playPauseBtn');
            const volumeSlider = document.getElementById('volumeSlider');
            const volumeIcon = document.getElementById('volumeIcon');
            const messageInput = document.getElementById('messageInput');
            const sendButton = document.getElementById('sendButton');
            const chatContainer = document.getElementById('chatContainer');

            setTimeout(() => {
                splashText.style.opacity = '1';
            }, 100);

            setTimeout(() => {
                splash.style.opacity = '0';
                splash.style.transition = 'opacity 1s';
                setTimeout(() => {
                    splash.style.display = 'none';
                    app.classList.remove('hidden');
                }, 1000);
            }, 2000);



            function updateVolumeIcon(value) {
                let icon = 'fa-volume-up';
                if (value == 0) icon = 'fa-volume-mute';
                else if (value < 50) icon = 'fa-volume-down';
                volumeIcon.innerHTML = `<i class="fas ${icon}"></i>`;
            }

            sendButton.addEventListener('click', () => {
                const message = messageInput.value.trim();
                if (message) {
                    statusvue.send();
                }
            });

            messageInput.addEventListener('keypress', (e) => {
                if (e.key === 'Enter') {
                    sendButton.click();
                }
            });
        });
    </script>
</body>
</html>